home *** CD-ROM | disk | FTP | other *** search
/ Delphi 5 for Professionals / DELPHI5.iso / AddOns / Components / TEECHART / Src Code / TEESURFA.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1998-10-24  |  35.3 KB  |  1,270 lines

  1. {**********************************************}
  2. {  TeeChart Pro 4.0                            }
  3. {                                              }
  4. {  TCustom3DSeries                             }
  5. {     TSurfaceSeries                           }
  6. {     TContourSeries                           }
  7. {  Copyright (c) 1995-1998 by David Berneda    }
  8. {**********************************************}
  9. {$I teedefs.inc}
  10. unit TeeSurfa;
  11.  
  12. interface
  13.  
  14. uses
  15.   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics,
  16.   Teengine, TeCanvas, Chart;
  17.  
  18. Const MaxAllowedCells={$IFDEF D1}127{$ELSE}500{$ENDIF}; { max 500 x 500 cells }
  19.       TeeSurfaceTriangles:Boolean=False;  { <-- True to draw triangles }
  20.  
  21. type
  22.   TChartSurfaceGetY=Function(Sender:TChartSeries; X,Z:Longint):Double of object;
  23.   TChartSurfaceGetColor=Procedure( Sender:TChartSeries;
  24.                                    ValueIndex:Longint;
  25.                                    Var Color:TColor) of object;
  26.  
  27.   TCustom3DSeries=class(TChartSeries)
  28.   private
  29.     FTimesZOrder : Longint;
  30.     FZValues     : TChartValueList;
  31.     Procedure SetTimesZOrder(Value:Longint);
  32.     Procedure SetZValues(Value:TChartValueList);
  33.     Procedure SetZValue(Index:Longint; Const Value:Double);
  34.     Function GetZValue(Index:Longint):Double;
  35.     Function IsZValuesStored:Boolean;
  36.   protected
  37.   public
  38.     Constructor Create(AOwner: TComponent); override;
  39.     Procedure Assign(Source:TPersistent); override;
  40.     Function AddXYZ( AX:Longint; Const AY:Double; AZ:Longint;
  41.                      Const AXLabel:String{$IFDEF D4}=''{$ENDIF};
  42.                      AColor:TColor{$IFDEF D4}=clTeeColor{$ENDIF}):Longint; virtual;
  43.     Procedure CalcZOrder; override;
  44.     Function IsValidSourceOf(Value:TChartSeries):Boolean; override;
  45.     Function MaxZValue:Double; override;
  46.     Function MinZValue:Double; override;
  47.     property ZValue[Index:Longint]:Double read GetZValue write SetZValue;
  48.     { to be published }
  49.     property TimesZOrder:Longint read FTimesZOrder write SetTimesZOrder default 3;
  50.     property ZValues:TChartValueList read FZValues write SetZValues stored IsZValuesStored;
  51.   end;
  52.  
  53.   TTeeCellsRow=Array[1..MaxAllowedCells] of Integer;
  54.   PTeeCellsRow=^TTeeCellsRow;
  55.  
  56.   TCustom3DGridSeries=class(TCustom3DSeries)
  57.   private
  58.     FEndColor     : TColor;
  59.     FGridIndex    : Array[1..MaxAllowedCells] of PTeeCellsRow;
  60.     FNumXValues   : Longint;
  61.     FNumZValues   : Longint;
  62.     FPalette      : TList;
  63.     FPaletteSteps : Longint;
  64.     FStartColor   : TColor;
  65.     FUseColorRange: Boolean;
  66.     FUsePalette   : Boolean;
  67.  
  68.     FOnGetYValue  : TChartSurfaceGetY;
  69.     FOnGetColor   : TChartSurfaceGetColor;
  70.  
  71.     { internal }
  72.     IInGallery   : Boolean;
  73.     IRangeRed    : Longint;
  74.     IEndRed      : Longint;
  75.     IRangeGreen  : Longint;
  76.     IEndGreen    : Longint;
  77.     IRangeBlue   : Longint;
  78.     IEndBlue     : Longint;
  79.     Procedure SetNumXValues(Value:Longint);
  80.     Procedure SetNumZValues(Value:Longint);
  81.     Function GetGridIndex(X,Z:Integer):Integer;
  82.     Procedure InternalSetGridIndex(X,Z,Value:Integer);
  83.     Procedure SetGridIndex(X,Z,Value:Integer);
  84.     Procedure CalcColorRange;
  85.     Procedure ClearGridIndex;
  86.   protected
  87.     Procedure SetPaletteSteps(Value:Longint);
  88.     Procedure SetStartColor(Value:TColor);
  89.     Procedure SetEndColor(Value:TColor);
  90.     Procedure SetUsePalette(Value:Boolean);
  91.     Procedure SetUseColorRange(Value:Boolean);
  92.     Procedure AddValues(Source:TChartSeries); override;
  93.     Function GetValueColor(ValueIndex:Longint):TColor; override;
  94.     Function GetValueColorValue(Const AValue:Double):TColor;
  95.     Procedure DoBeforeDrawChart; override;
  96.   public
  97.     RedFactor    : Double;
  98.     GreenFactor  : Double;
  99.     BlueFactor   : Double;
  100.     Constructor Create(AOwner: TComponent); override;
  101.     Destructor Destroy; override;
  102.  
  103.     Function AddPalette(Const Value:Double; Color:TColor):Longint;
  104.     Procedure Assign(Source:TPersistent); override;
  105.     Function CanCreateValues:Boolean;
  106.     Procedure Clear; override;
  107.     Procedure ClearPalette;
  108.     Procedure CreateDefaultPalette(NumSteps:Longint);
  109.     Procedure CreateValues(NumX,NumZ:Longint); virtual;
  110.     Function CountLegendItems:Integer; override;
  111.     Procedure FillGridIndex;
  112.     Procedure FillSampleValues(NumValues:Longint); override;
  113.     Procedure GalleryChanged3D(Is3D:Boolean); override;
  114.     Function GetSurfacePaletteColor(Const Y:Double):TColor;
  115.     Function GetXZValue(X,Z:Longint):Double; virtual;
  116.     Function LegendItemColor(LegendIndex:Longint):TColor; override;
  117.     Function LegendString( LegendIndex:Integer;
  118.                            LegendTextStyle:TLegendTextStyle ):String; override;
  119.     Function NumSampleValues:Longint; override;
  120.     Procedure ReCreateValues;
  121.  
  122.     property EndColor:TColor read FEndColor write SetEndColor default clWhite;
  123.     property GridIndex[X,Z:Integer]:Integer read GetGridIndex write SetGridIndex;
  124.  
  125.     property NumXValues:Longint read FNumXValues write SetNumXValues default 10;
  126.     property NumZValues:Longint read FNumZValues write SetNumZValues default 10;
  127.     property Palette:TList read FPalette;
  128.     property PaletteSteps:Longint read FPaletteSteps write SetPaletteSteps default 32;
  129.     property StartColor:TColor read FStartColor write SetStartColor default clNavy;
  130.     property UseColorRange:Boolean read FUseColorRange write SetUseColorRange default True;
  131.     property UsePalette:Boolean read FUsePalette write SetUsePalette default False;
  132.     { events }
  133.     property OnGetYValue:TChartSurfaceGetY read FOnGetYValue write FOnGetYValue;
  134.     property OnGetColor:TChartSurfaceGetColor read FOnGetColor write FOnGetColor;
  135.   end;
  136.  
  137. type
  138.   TSurfaceSeries=class(TCustom3DGridSeries)
  139.   private
  140.     { Private declarations }
  141.     FWireFrame      : Boolean;
  142.     FDotFrame       : Boolean;
  143.     FPen            : TChartPen;
  144.     FBrush          : TChartBrush;
  145.     { internal }
  146.     FSameBrush      : Boolean;
  147.     Points          : TFourPoints;
  148.     ValueIndex0     : Integer;
  149.     ValueIndex1     : Integer;
  150.     ValueIndex2     : Integer;
  151.     ValueIndex3     : Integer;
  152.     INextXCell      : Integer;
  153.     INextZCell      : Integer;
  154.     Procedure SetPen(Value:TChartPen);
  155.     Procedure SetBrush(Value:TChartBrush);
  156.   protected
  157.     { Protected declarations }
  158.     Function ExistFourGridIndex(X,Z:Integer):Boolean;
  159.     Procedure SetDotFrame(Value:Boolean);
  160.     Procedure SetWireFrame(Value:Boolean);
  161.     Procedure DrawAllValues; override;
  162.     Procedure DrawCell(x,z:Longint); virtual;
  163.     Function CalcPointPos(Index:Longint):TPoint;
  164.   public
  165.     { Public declarations }
  166.     Constructor Create(AOwner: TComponent); override;
  167.     Destructor Destroy; override;
  168.     Procedure Assign(Source:TPersistent); override;
  169.     Function Clicked(x,y:Integer):Longint; override;
  170.     Function GetEditorClass:String; override;
  171.     Procedure PrepareForGallery(IsEnabled:Boolean); override;
  172.   published
  173.     { Published declarations }
  174.     property Brush:TChartBrush read FBrush write SetBrush;
  175.     property DotFrame:Boolean read FDotFrame write SetDotFrame default False;
  176.     property EndColor;
  177.     property NumXValues;
  178.     property NumZValues;
  179.     property Pen:TChartPen read FPen write SetPen;
  180.     property PaletteSteps;
  181.     property StartColor;
  182.     property UseColorRange;
  183.     property UsePalette;
  184.     property WireFrame:Boolean read FWireFrame write SetWireFrame default False;
  185.     property TimesZOrder;
  186.     property XValues;
  187.     property YValues;
  188.     property ZValues;
  189.   { events }
  190.     property OnGetYValue;
  191.     property OnGetColor;
  192.   end;
  193.  
  194. Const
  195.   MaxLevels={$IFDEF D1}100{$ELSE}250{$ENDIF};
  196.  
  197. type
  198.   TContourSeries=class;
  199.   
  200.   TOnGetLevelEvent=procedure( Sender:TContourSeries; LevelIndex:Integer;
  201.                               Var Value:Double; Var Color:TColor) of object;
  202.  
  203.   TContourSeries=class(TCustom3DGridSeries)
  204.   private
  205.     FNumLevels      : Integer;
  206.     FLevels         : Array[0..MaxLevels] of Double;
  207.     FLevelColors    : Array[0..MaxLevels] of TColor;
  208.     FPen            : TChartPen;
  209.     FYPosition      : Double;
  210.     FYPositionLevel : Boolean;
  211.     FOnGetLevel     : TOnGetLevelEvent;
  212.     Procedure SetNumLevels(Value:Integer);
  213.     Procedure SetPen(Value:TChartPen);
  214.     Procedure SetYPosition(Const Value:Double);
  215.     Procedure SetYPositionLevel(Value:Boolean);
  216.   protected
  217.     procedure DrawAllValues; override;
  218.     Procedure DoBeforeDrawChart; override;
  219.   public
  220.     Constructor Create(AOwner: TComponent); override;
  221.     Destructor Destroy; override;
  222.  
  223.     Procedure Assign(Source:TPersistent); override;
  224.     procedure FillSampleValues(NumValues:Longint); override;
  225.     Procedure PrepareForGallery(IsEnabled:Boolean); override;
  226.     Function GetEditorClass:String; override;
  227.     Function CountLegendItems:Integer; override;
  228.     Function LegendItemColor(LegendIndex:Longint):TColor; override;
  229.     Function LegendString( LegendIndex:Integer;
  230.                            LegendTextStyle:TLegendTextStyle ):String; override;
  231.   published
  232.     property ColorEachPoint default True;
  233.     property EndColor;
  234.     property NumLevels:Integer read FNumLevels write SetNumLevels default 10;
  235.     property NumXValues;
  236.     property NumZValues;
  237.     property PaletteSteps;
  238.     property Pen:TChartPen read FPen write SetPen;
  239.     property StartColor;
  240.     property TimesZOrder;
  241.     property UseColorRange;
  242.     property UsePalette;
  243.     property XValues;
  244.     property YPosition:Double read FYPosition write SetYPosition;
  245.     property YPositionLevel:Boolean read FYPositionLevel write SetYPositionLevel default False;
  246.     property YValues;
  247.     property ZValues;
  248.   { events }
  249.     property OnGetYValue;
  250.     property OnGetLevel:TOnGetLevelEvent read FOnGetLevel write FOnGetLevel;
  251.   end;
  252.  
  253. implementation
  254.  
  255. Uses TeeProcs,TeeProCo,TeeConst;
  256.  
  257. { TCustom3DSeries }
  258. Constructor TCustom3DSeries.Create(AOwner: TComponent);
  259. Begin
  260.   inherited Create(AOwner);
  261.   HasZValues:=True;
  262.   CalcVisiblePoints:=False;
  263.   FZValues :=TChartValueList.Create(Self,'Z'); { <-- dont translate ! }
  264.   XValues.Order:=loNone;
  265.   FTimesZOrder:=3;
  266. end;
  267.  
  268. Procedure TCustom3DSeries.SetZValues(Value:TChartValueList);
  269. Begin
  270.   SetChartValueList(FZValues,Value); { standard method }
  271. End;
  272.  
  273. Procedure TCustom3DSeries.CalcZOrder;
  274. Begin
  275.   inherited CalcZOrder;
  276.   ParentChart.MaxZOrder:=FTimesZOrder;
  277. end;
  278.  
  279. Function TCustom3DSeries.AddXYZ( AX:Longint; Const AY:Double; AZ:Longint;
  280.                                 Const AXLabel:String; AColor:TColor):Longint;
  281. Begin
  282.   result:=AddXY(AX,AY,AXLabel,AColor); { standard add X,Y }
  283.   FZValues.TempValue:=AZ;
  284.   AddValue(result);
  285. end;
  286.  
  287. Function TCustom3DSeries.IsValidSourceOf(Value:TChartSeries):Boolean;
  288. begin
  289.   result:=Value is TCustom3DSeries;
  290. end;
  291.  
  292. Procedure TCustom3DSeries.SetTimesZOrder(Value:Longint);
  293. Begin
  294.   SetLongintProperty(FTimesZOrder,Value);
  295. End;
  296.  
  297. Function TCustom3DSeries.MaxZValue:Double;
  298. begin
  299.   result:=FZValues.MaxValue;
  300. end;
  301.  
  302. Function TCustom3DSeries.MinZValue:Double;
  303. begin
  304.   result:=FZValues.MinValue;
  305. end;
  306.  
  307. Procedure TCustom3DSeries.Assign(Source:TPersistent);
  308. begin
  309.   if Source is TCustom3DSeries then
  310.   With TCustom3DSeries(Source) do
  311.   begin
  312.     Self.FZValues.Assign(FZValues);
  313.     Self.FTimesZOrder  :=FTimesZOrder;
  314.   end;
  315.   inherited Assign(Source);
  316. end;
  317.  
  318. Procedure TCustom3DSeries.SetZValue(Index:Longint; Const Value:Double);
  319. Begin
  320.   ZValues.Value[Index]:=Value;
  321. End;
  322.  
  323. Function TCustom3DSeries.GetZValue(Index:Longint):Double;
  324. Begin
  325.   result:=ZValues.Value[Index];
  326. End;
  327.  
  328. Function TCustom3DSeries.IsZValuesStored:Boolean;
  329. begin
  330.   With FZValues do
  331.   result:=DateTime or (Name<>'Z') or (Multiplier<>1) or (Order<>loNone) or
  332.                    (ValueSource<>'');
  333. end;
  334.  
  335. { TCustom3DGridSeries }
  336. Constructor TCustom3DGridSeries.Create(AOwner: TComponent);
  337. Begin
  338.   inherited Create(AOwner);
  339.   FNumXValues:=10;
  340.   FNumZValues:=10;
  341.   Clear;
  342.   FUseColorRange:=True;
  343.   FPalette:=TList.Create;
  344.   FPaletteSteps:=32;
  345.   FStartColor:=clNavy;
  346.   FEndColor:=clWhite;
  347.   { Palette Modifiers }
  348.   RedFactor:=2.0;
  349.   GreenFactor:=1;
  350.   BlueFactor:=1;
  351.   CalcColorRange;
  352.   {$IFDEF TEETRIAL}
  353.   TeeTrial(ComponentState);
  354.   {$ENDIF}
  355. End;
  356.  
  357. Destructor TCustom3DGridSeries.Destroy;
  358. begin
  359.   ClearPalette;
  360.   FPalette.Free;
  361.   ClearGridIndex;
  362.   inherited Destroy;
  363. end;
  364.  
  365. Procedure TCustom3DGridSeries.ClearGridIndex;
  366. var t:Integer;
  367. begin
  368.   for t:=1 to MaxAllowedCells do
  369.   if Assigned(FGridIndex[t]) then
  370.   begin
  371.     Dispose(FGridIndex[t]);
  372.     FGridIndex[t]:=nil;
  373.   end;
  374. end;
  375.  
  376. Procedure TCustom3DGridSeries.Clear;
  377. begin
  378.   inherited Clear;
  379.   XValues.Order:=loNone;
  380.   ClearGridIndex;
  381. end;
  382.  
  383. Function TCustom3DGridSeries.GetGridIndex(X,Z:Integer):Integer;
  384. begin
  385.   if Assigned(FGridIndex[X]) then
  386.      result:=FGridIndex[x]^[z]
  387.   else
  388.      result:=-1;
  389. end;
  390.  
  391. Procedure TCustom3DGridSeries.SetGridIndex(X,Z,Value:Integer);
  392. begin
  393.   if (X>=1) and (X<=MaxAllowedCells) and
  394.      (Z>=1) and (Z<=MaxAllowedCells) then InternalSetGridIndex(x,z,value);
  395. end;
  396.  
  397. Procedure TCustom3DGridSeries.InternalSetGridIndex(X,Z,Value:Integer);
  398. var t:Integer;
  399. begin
  400.   if not Assigned(FGridIndex[x]) then
  401.   begin
  402.     New(FGridIndex[x]);
  403.     for t:=1 to MaxAllowedCells do FGridIndex[x]^[t]:=-1;
  404.   end;
  405.   FGridIndex[x]^[z]:=Value;
  406. end;
  407.  
  408. Procedure TCustom3DGridSeries.FillGridIndex;
  409. var t    : Longint;
  410.     x    : Integer;
  411.     z    : Integer;
  412.     MinX : Double;
  413.     MinZ : Double;
  414. begin
  415.   MinX:=XValues.MinValue;
  416.   MinZ:=ZValues.MinValue;
  417.   for t:=0 to Count-1 do
  418.   begin
  419.     x:=1+Round(XValues.Value[t]-MinX);
  420.     z:=1+Round(ZValues.Value[t]-MinZ);
  421.     InternalSetGridIndex(X,Z,t);
  422.     if X>FNumXValues then FNumXValues:=X;
  423.     if Z>FNumZValues then FNumZValues:=Z;
  424.   end;
  425. end;
  426.  
  427. Function TCustom3DGridSeries.GetXZValue(X,Z:Longint):Double;
  428. Begin
  429.   if Assigned(FOnGetYValue) then result:=FOnGetYValue(Self,X,Z)
  430.   else  { default sample random surface value formula }
  431.   if (csDesigning in ComponentState) or
  432.      (IInGallery) then
  433.      result:=0.5*sqr(Cos(x/(FNumXValues*0.2)))+
  434.                  sqr(Cos(z/(FNumZValues*0.2)))-
  435.                  cos(z/(FNumZValues*0.5))
  436.   else
  437.      result:=0;
  438. end;
  439.  
  440. Function TCustom3DGridSeries.NumSampleValues:Longint;
  441. begin
  442.   result:=15; { 15x15 default }
  443. end;
  444.  
  445. Procedure TCustom3DGridSeries.ReCreateValues;
  446. Begin
  447.   CreateValues(FNumXValues,FNumZValues);
  448. end;
  449.  
  450. Procedure TCustom3DGridSeries.SetNumXValues(Value:Longint);
  451. Begin
  452.   if Value<>FNumXValues then
  453.   begin
  454.     FNumXValues:=Value;
  455.     ReCreateValues;
  456.   end;
  457. End;
  458.  
  459. Procedure TCustom3DGridSeries.SetNumZValues(Value:Longint);
  460. Begin
  461.   if Value<>FNumZValues then
  462.   begin
  463.     FNumZValues:=Value;
  464.     ReCreateValues;
  465.   end;
  466. End;
  467.  
  468. Procedure TCustom3DGridSeries.AddValues(Source:TChartSeries);
  469. Begin
  470.   if Source is TCustom3DGridSeries then
  471.   With TCustom3DGridSeries(Source) do
  472.   begin
  473.     Self.FNumXValues:=FNumXValues;
  474.     Self.FNumZValues:=FNumZValues;
  475.   end;
  476.   inherited AddValues(Source);
  477.   FillGridIndex;
  478.   Repaint;
  479. end;
  480.  
  481. Procedure TCustom3DGridSeries.Assign(Source:TPersistent);
  482. begin
  483.   if Source is TCustom3DGridSeries then
  484.   With TCustom3DGridSeries(Source) do
  485.   begin
  486.     Self.FNumXValues   :=FNumXValues;
  487.     Self.FNumZValues   :=FNumZValues;
  488.     Self.FUsePalette   :=FUsePalette;
  489.     Self.FUseColorRange:=FUseColorRange;
  490.     Self.FStartColor   :=FStartColor;
  491.     Self.FEndColor     :=FEndColor;
  492.     Self.FPaletteSteps :=FPaletteSteps;
  493.   end;
  494.   inherited Assign(Source);
  495. end;
  496.  
  497. Function TCustom3DGridSeries.CanCreateValues:Boolean;
  498. begin
  499.   result:= Assigned(FOnGetYValue) or (csDesigning in ComponentState)
  500.            or IInGallery;
  501. end;
  502.  
  503. Procedure TCustom3DGridSeries.CreateValues(NumX,NumZ:Longint);
  504. var x           : Longint;
  505.     z           : Longint;
  506.     OldCapacity : Longint;
  507. Begin
  508.   if CanCreateValues then
  509.   begin
  510.     FNumXValues:=NumX;
  511.     FNumZValues:=NumZ;
  512.     OldCapacity:=TeeDefaultCapacity;
  513.     TeeDefaultCapacity:=NumX*NumZ;
  514.     try
  515.       Clear;
  516.       for x:=1 to NumX do
  517.           for z:=1 to NumZ do AddXYZ(X,GetXZValue(X,Z),Z {$IFNDEF D4},'',clTeeColor{$ENDIF});
  518.       RefreshSeries;
  519.     finally
  520.       TeeDefaultCapacity:=OldCapacity;
  521.     end;
  522.     CreateDefaultPalette(FPaletteSteps);
  523.   end;
  524. End;
  525.  
  526. Procedure TCustom3DGridSeries.FillSampleValues(NumValues:Longint);
  527. var OldGallery : Boolean;
  528. Begin
  529.   OldGallery:=IInGallery;
  530.   IInGallery:=True;
  531.   try
  532.     if NumValues>0 then
  533.     begin
  534.       FNumXValues:=MinLong(MaxAllowedCells,NumValues);
  535.       FNumZValues:=FNumXValues;
  536.     end;
  537.     CreateValues(FNumXValues,FNumZValues);
  538.   finally
  539.     IInGallery:=OldGallery;
  540.   end;
  541. End;
  542.  
  543. Procedure TCustom3DGridSeries.CalcColorRange;
  544. Begin
  545.   IEndRed    :=GetRValue(FEndColor);
  546.   IEndGreen  :=GetGValue(FEndColor);
  547.   IEndBlue   :=GetBValue(FEndColor);
  548.   IRangeRed  :=Longint(GetRValue(FStartColor))-IEndRed;
  549.   IRangeGreen:=Longint(GetGValue(FStartColor))-IEndGreen;
  550.   IRangeBlue :=Longint(GetBValue(FStartColor))-IEndBlue;
  551. end;
  552.  
  553. Procedure TCustom3DGridSeries.SetStartColor(Value:TColor);
  554. Begin
  555.   SetColorProperty(FStartColor,Value);
  556.   CalcColorRange;
  557. End;
  558.  
  559. Procedure TCustom3DGridSeries.SetEndColor(Value:TColor);
  560. Begin
  561.   SetColorProperty(FEndColor,Value);
  562.   CalcColorRange;
  563. End;
  564.  
  565. type PGridPalette=^TGridPalette;
  566.      TGridPalette=Record
  567.        UpToValue : Double;
  568.        Color     : TColor;
  569.      end;
  570.  
  571. Function TCustom3DGridSeries.AddPalette(Const Value:Double; Color:TColor):Longint;
  572. var t:Longint;
  573.     tmp:PGridPalette;
  574. Begin
  575.   New(tmp);
  576.   tmp^.UpToValue:=Value;
  577.   tmp^.Color:=Color;
  578.   for t:=0 to FPalette.Count-1 do
  579.   begin
  580.     if Value<TGridPalette(FPalette[t]^).UpToValue then
  581.     begin
  582.       FPalette.Insert(t,tmp);
  583.       result:=t;
  584.       exit;
  585.     end;
  586.   end;
  587.   result:=FPalette.Add(tmp);
  588. End;
  589.  
  590. Procedure TCustom3DGridSeries.ClearPalette;
  591. var t:Integer;
  592. Begin
  593.   for t:=0 to FPalette.Count-1 do Dispose(PGridPalette(FPalette[t]));
  594.   FPalette.Clear;
  595. end;
  596.  
  597. Procedure TCustom3DGridSeries.DoBeforeDrawChart;
  598. begin
  599.   if Count>0 then
  600.   begin
  601.     FillGridIndex;
  602.     if FPalette.Count=0 then CreateDefaultPalette(FPaletteSteps);
  603.   end;
  604. end;
  605.  
  606. Function TCustom3DGridSeries.CountLegendItems:Integer;
  607. begin
  608.   result:=FPalette.Count;
  609. end;
  610.  
  611. Function TCustom3DGridSeries.LegendString( LegendIndex:Integer;
  612.                                            LegendTextStyle:TLegendTextStyle ):String;
  613. begin
  614.   With FPalette do
  615.   if Count>LegendIndex then
  616.      result:=FormatFloat(ValueFormat,TGridPalette(FPalette[Count-LegendIndex-1]^).UpToValue)
  617.   else
  618.      result:='';
  619. end;
  620.  
  621. Function TCustom3DGridSeries.LegendItemColor(LegendIndex:Longint):TColor;
  622. begin
  623.   result:=GetValueColorValue(TGridPalette(FPalette[FPalette.Count-LegendIndex-1]^).UpToValue)
  624. end;
  625.  
  626. Procedure TCustom3DGridSeries.CreateDefaultPalette(NumSteps:Longint);
  627. Const Delta=127.0;
  628. var t:Longint;
  629.     tmp,Scale,ScaleValue:Double;
  630. Begin
  631.   ClearPalette;
  632.   FPalette.Capacity:=NumSteps+1;
  633.   Scale:=pi/NumSteps;
  634.   ScaleValue:=(YValues.MaxValue-YValues.MinValue)/NumSteps;
  635.   for t:=1 to NumSteps do
  636.   begin
  637.     tmp:=Scale*t;
  638.     AddPalette(YValues.MinValue+ScaleValue*t,
  639.                         RGB( Trunc(Delta * (Sin(tmp/RedFactor)+1)) ,
  640.                              Trunc(Delta * (Sin(tmp/GreenFactor)+1)),
  641.                              Trunc(Delta * (Cos(tmp/BlueFactor)+1))));
  642.   end;
  643. end;
  644.  
  645. Procedure TCustom3DGridSeries.SetUseColorRange(Value:Boolean);
  646. Begin
  647.   SetBooleanProperty(FUseColorRange,Value);
  648. End;
  649.  
  650. Procedure TCustom3DGridSeries.SetUsePalette(Value:Boolean);
  651. Begin
  652.   SetBooleanProperty(FUsePalette,Value);
  653.   if Value and (FPalette.Count=0) then CreateDefaultPalette(FPaletteSteps);
  654. End;
  655.  
  656. Function TCustom3DGridSeries.GetSurfacePaletteColor(Const Y:Double):TColor;
  657. Var t,tmpCount:Longint;
  658. Begin
  659.   With FPalette do
  660.   begin
  661.     tmpCount:=Count-1;
  662.     for t:=0 to tmpCount do
  663.     if TGridPalette(Items[t]^).UpToValue>Y then
  664.     Begin
  665.       if t>0 then result:=TGridPalette(Items[t]^).Color
  666.              else result:=TGridPalette(First^).Color;
  667.       exit;
  668.     end;
  669.     result:=TGridPalette(Last^).Color;
  670.   end;
  671. End;
  672.  
  673. Function TCustom3DGridSeries.GetValueColorValue(Const AValue:Double):TColor;
  674. var Percent   : Double;
  675.     tmpDeltaY : Double;
  676. begin
  677.   if FUseColorRange then
  678.   With YValues do
  679.   begin
  680.     tmpDeltaY:=(MaxValue-MinValue);
  681.     if tmpDeltaY=0 then result:=FEndColor
  682.     else
  683.     begin
  684.       Percent:=(AValue-MinValue)/tmpDeltaY;
  685.       result:=RGB( IEndRed  +Round(Percent*IRangeRed),
  686.                    IEndGreen+Round(Percent*IRangeGreen),
  687.                    IEndBlue +Round(Percent*IRangeBlue));
  688.     end;
  689.   end
  690.   else
  691.   if FUsePalette and (FPalette.Count>0) then
  692.      result:=GetSurfacePaletteColor(AValue)
  693.   else
  694.      result:=SeriesColor;
  695. end;
  696.  
  697. Function TCustom3DGridSeries.GetValueColor(ValueIndex:Longint):TColor;
  698. Begin
  699.   result:=inherited GetValueColor(ValueIndex);
  700.   if result<>clNone then result:=GetValueColorValue(YValue[ValueIndex]);
  701.   if Assigned(FOnGetColor) then FOnGetColor(Self,ValueIndex,result);
  702. End;
  703.  
  704. Procedure TCustom3DGridSeries.GalleryChanged3D(Is3D:Boolean);
  705. begin
  706.   With ParentChart.View3DOptions do
  707.   begin
  708.     Zoom:=60;
  709.     VertOffset:=-2;
  710.     if Is3D then
  711.     begin
  712.       Rotation:=335;
  713.       Elevation:=340;
  714.       Perspective:=60;
  715.     end
  716.     else
  717.     begin
  718.       Rotation:=0;
  719.       Elevation:=270;
  720.       Perspective:=0;
  721.     end;
  722.   end;
  723. end;
  724.  
  725. Procedure TCustom3DGridSeries.SetPaletteSteps(Value:Longint);
  726. Begin
  727.   FPaletteSteps:=Value;
  728.   CreateDefaultPalette(FPaletteSteps);
  729. End;
  730.  
  731. { TSurfaceSeries }
  732. Constructor TSurfaceSeries.Create(AOwner: TComponent);
  733. Begin
  734.   inherited Create(AOwner);
  735.   INextXCell:=-1;
  736.   INextZCell:=-1;
  737.   FPen:=CreateChartPen;
  738.   FBrush:=TChartBrush.Create(CanvasChanged);
  739. End;
  740.  
  741. Destructor TSurfaceSeries.Destroy;
  742. Begin
  743.   FBrush.Free;
  744.   FPen.Free;
  745.   inherited Destroy;
  746. End;
  747.  
  748. Procedure TSurfaceSeries.PrepareForGallery(IsEnabled:Boolean);
  749. begin
  750.   inherited PrepareForGallery(IsEnabled);
  751.   IInGallery:=True;
  752.   UseColorRange:=False;
  753.   if IsEnabled then Pen.Color:=clBlack
  754.                else Pen.Color:=clGray;
  755.   UsePalette:=IsEnabled;
  756.   CreateValues(10,10);
  757. end;
  758.  
  759. Function TSurfaceSeries.CalcPointPos(Index:Longint):TPoint;
  760. begin
  761.   result.x:=GetHorizAxis.CalcXPosValue(GetxValue(Index));
  762.   result.y:=GetVertAxis.CalcYPosValue(GetyValue(Index));
  763. end;
  764.  
  765. Function TSurfaceSeries.Clicked(x,y:Integer):Longint;
  766. var XIndex : Integer;
  767.     ZIndex : Integer;
  768. begin
  769.   result:=TeeNoPointClicked;
  770.   if Count>0 then
  771.   begin
  772.     INextXCell:=-1;
  773.     INextZCell:=-1;
  774.     for XIndex:=2 to FNumXValues do
  775.       for ZIndex:=2 to FNumZValues do { front to back... }
  776.       begin
  777.         if ExistFourGridIndex(XIndex,ZIndex) then
  778.         if PointInPolygon(Point(x,y),Points) then
  779.         begin
  780.           result:=ValueIndex0;
  781.           exit;
  782.         end;
  783.       end;
  784.   end;
  785. end;
  786.  
  787. Procedure TSurfaceSeries.SetPen(Value:TChartPen);
  788. Begin
  789.   FPen.Assign(Value);
  790. End;
  791.  
  792. Procedure TSurfaceSeries.SetBrush(Value:TChartBrush);
  793. Begin
  794.   FBrush.Assign(Value);
  795. End;
  796.  
  797. Procedure TSurfaceSeries.DrawAllValues;
  798. var x,z:Longint;
  799. Begin
  800.   if Count>0 then
  801.   begin
  802.     With ParentChart.Canvas do
  803.     begin
  804.       Pen.Assign(FPen);
  805.       if (not FPen.Visible) and
  806.          (not FWireFrame)   and
  807.          (not FDotFrame) then Pen.Style:=psClear;
  808.       Brush.Assign(FBrush);
  809.       Brush.Color:=SeriesColor;
  810.       if FUseColorRange or FUsePalette then FSameBrush:=False;
  811.       if FWireFrame or FDotFrame then
  812.       Begin
  813.         Brush.Style:=bsClear;
  814.         FSameBrush:=True;
  815.       end;
  816.     end;
  817.     if ParentChart.DepthAxis.Inverted then
  818.     begin
  819.       INextZCell:=1;
  820.       if GetHorizAxis.Inverted then
  821.       begin
  822.         INextXCell:=1;
  823.         for x:=FNumXValues-1 downto 1 do
  824.             for z:=1 to FNumZValues-1 do DrawCell(x,z);
  825.       end
  826.       else
  827.       begin
  828.         INextXCell:=-1;
  829.         for x:=2 to FNumXValues do
  830.             for z:=1 to FNumZValues-1 do DrawCell(x,z);
  831.       end;
  832.     end
  833.     else
  834.     begin
  835.       INextZCell:=-1;
  836.       if GetHorizAxis.Inverted then
  837.       begin
  838.         INextXCell:=1;
  839.         for x:=FNumXValues-1 downto 1 do
  840.             for z:=FNumZValues downto 2 do DrawCell(x,z);
  841.       end
  842.       else
  843.       begin
  844.         INextXCell:=-1;
  845.         for x:=2 to FNumXValues do
  846.             for z:=FNumZValues downto 2 do DrawCell(x,z);
  847.       end;
  848.     end;
  849.   end;
  850. End;
  851.  
  852. Function TSurfaceSeries.ExistFourGridIndex(X,Z:Integer):Boolean;
  853. begin
  854.   result:=False;
  855.   ValueIndex0:=GetGridIndex(x,Z);
  856.   if ValueIndex0>-1 then
  857.   begin
  858.     ValueIndex1:=GetGridIndex(x+INextXCell,Z);
  859.     if ValueIndex1>-1 then
  860.     begin
  861.       ValueIndex2:=GetGridIndex(x+INextXCell,Z+INextZCell);
  862.       if ValueIndex2>-1 then
  863.       begin
  864.         ValueIndex3:=GetGridIndex(x,Z+INextZCell);
  865.         result:=ValueIndex3>-1;
  866.         if result then
  867.         begin
  868.           Points[0]:=CalcPointPos(ValueIndex0);
  869.           Points[1]:=CalcPointPos(ValueIndex1);
  870.           Points[2]:=CalcPointPos(ValueIndex2);
  871.           Points[3]:=CalcPointPos(ValueIndex3);
  872.         end;
  873.       end;
  874.     end;
  875.   end;
  876. end;
  877.  
  878. Procedure TSurfaceSeries.DrawCell(X,Z:Longint);
  879. var tmpColor : TColor;
  880.     Z0       : Integer;
  881.     Z1       : Integer;
  882.  
  883.   Procedure DrawTheCell;
  884.   var P:Array[0..2] of TPoint;
  885.   begin
  886.     if FDotFrame then
  887.     begin
  888.       With ParentChart.Canvas do
  889.       begin
  890.         With Points[0] do Pixels3D[X,Y,Z0]:=GetValueColor(ValueIndex0);
  891.         With Points[1] do Pixels3D[X,Y,Z0]:=GetValueColor(ValueIndex1);
  892.         With Points[2] do Pixels3D[X,Y,Z1]:=GetValueColor(ValueIndex2);
  893.         With Points[3] do Pixels3D[X,Y,Z1]:=GetValueColor(ValueIndex3);
  894.       end;
  895.     end
  896.     else
  897.     With ParentChart.Canvas do
  898.     if TeeSurfaceTriangles then
  899.     begin
  900.       P[0]:=Calculate3DPosition(Points[0].X,Points[0].y,Z0);
  901.       P[1]:=Calculate3DPosition(Points[1].X,Points[1].y,Z0);
  902.       P[2]:=Calculate3DPosition(Points[3].X,Points[3].y,Z1);
  903.       Polygon(P);
  904.       P[0]:=Calculate3DPosition(Points[2].X,Points[2].y,Z1);
  905.       Polygon(P);
  906.     end
  907.     else PlaneFour3D(Points,Z0,Z1);
  908.   end;
  909.  
  910. Begin
  911.   if ExistFourGridIndex(X,Z) then
  912.   begin
  913.     With ParentChart.DepthAxis do
  914.     begin
  915.       Z:=Z+Round(ZValues.MinValue)-1;
  916.       Z0:=CalcYPosValue(Z);
  917.       Z1:=CalcYPosValue(Z+INextZCell);
  918.     end;
  919.  
  920.     if FSameBrush then DrawTheCell
  921.     else
  922.     begin
  923.       tmpColor:=GetValueColor(ValueIndex0);
  924.       if tmpColor<>clNone then
  925.       begin
  926.         ParentChart.Canvas.Brush.Color:=tmpColor;
  927.         DrawTheCell;
  928.       end;
  929.     end;
  930.   end;
  931. end;
  932.  
  933. Procedure TSurfaceSeries.SetWireFrame(Value:Boolean);
  934. Begin
  935.   if Value then FPen.Visible:=True;
  936.   SetBooleanProperty(FWireFrame,Value);
  937.   if FWireFrame then FDotFrame:=False;
  938. End;
  939.  
  940. Procedure TSurfaceSeries.SetDotFrame(Value:Boolean);
  941. Begin
  942.   if Value then FPen.Visible:=True;
  943.   SetBooleanProperty(FDotFrame,Value);
  944.   if FDotFrame then FWireFrame:=False;
  945. End;
  946.  
  947. Function TSurfaceSeries.GetEditorClass:String;
  948. Begin
  949.   result:='TSurfaceSeriesEditor'; { <-- dont translate ! }
  950. end;
  951.  
  952. Procedure TSurfaceSeries.Assign(Source:TPersistent);
  953. begin
  954.   if Source is TSurfaceSeries then
  955.   With TSurfaceSeries(Source) do
  956.   begin
  957.     Self.FPen.Assign(FPen);
  958.     Self.FBrush.Assign(FBrush);
  959.     Self.FWireFrame:= FWireFrame;
  960.     Self.FDotFrame := FDotFrame;
  961.   end;
  962.   inherited Assign(Source);
  963. end;
  964.  
  965. { TContourSeries }
  966. Constructor TContourSeries.Create(AOwner: TComponent);
  967. Begin
  968.   inherited Create(AOwner);
  969.   FPen:=CreateChartPen;
  970.   ColorEachPoint:=True;
  971.   FNumLevels:=10;
  972.   FYPositionLevel:=False;
  973.   FYPosition:=0;
  974.   {$IFDEF TEETRIAL}
  975.   TeeTrial(ComponentState);
  976.   {$ENDIF}
  977. End;
  978.  
  979. Destructor TContourSeries.Destroy;
  980. begin
  981.   FPen.Free;
  982.   inherited Destroy;
  983. end;
  984.  
  985. Procedure TContourSeries.Assign(Source:TPersistent);
  986. begin
  987.   if Source is TContourSeries then
  988.   With TContourSeries(Source) do
  989.   begin
  990.     Self.FPen.Assign(FPen);
  991.     Self.FNumLevels:=FNumLevels;
  992.     Self.FYPosition:=FYPosition;
  993.     Self.FYPositionLevel:=FYPositionLevel;
  994.   end;
  995.   inherited Assign(Source);
  996. end;
  997.  
  998. Procedure TContourSeries.SetNumLevels(Value:Integer);
  999. begin
  1000.   SetIntegerProperty(FNumLevels,Value);
  1001. end;
  1002.  
  1003. Procedure TContourSeries.SetYPosition(Const Value:Double);
  1004. begin
  1005.   SetDoubleProperty(FYPosition,Value);
  1006. end;
  1007.  
  1008. Procedure TContourSeries.SetYPositionLevel(Value:Boolean);
  1009. begin
  1010.   SetBooleanProperty(FYPositionLevel,Value);
  1011. end;
  1012.  
  1013. procedure TContourSeries.DrawAllValues;
  1014. Var x1    : Integer;
  1015.     x2    : Integer;
  1016.     z1    : Integer;
  1017.     z2    : Integer;
  1018.     DifY  : Array[0..4] of Double;
  1019.     CellX : Array[0..4] of Integer;
  1020.     CellZ : Array[0..4] of Integer;
  1021.     m1    : Integer;
  1022.     m3    : Integer;
  1023.  
  1024.   Procedure CalcLinePoints(Side:Integer);
  1025.  
  1026.     Procedure PointSect1(p1,p2:Integer);
  1027.     Var tmp:Double;
  1028.     begin
  1029.       tmp:=DifY[p2]-DifY[p1];
  1030.       if tmp<>0 then
  1031.       begin
  1032.         x1:=Round( 1.0*(DifY[p2]*CellX[p1]-DifY[p1]*CellX[p2])/tmp );
  1033.         z1:=Round( 1.0*(DifY[p2]*CellZ[p1]-DifY[p1]*CellZ[p2])/tmp );
  1034.       end;
  1035.     end;
  1036.  
  1037.     Procedure PointSect2(p1,p2:Integer);
  1038.     Var tmp:Double;
  1039.     begin
  1040.       tmp:=DifY[p2]-DifY[p1];
  1041.       if tmp<>0 then
  1042.       begin
  1043.         x2:=Round( 1.0*(DifY[p2]*CellX[p1]-DifY[p1]*CellX[p2])/tmp );
  1044.         z2:=Round( 1.0*(DifY[p2]*CellZ[p1]-DifY[p1]*CellZ[p2])/tmp );
  1045.       end;
  1046.     end;
  1047.  
  1048.   begin
  1049.     case Side of
  1050.      1,4,6: begin x1:=CellX[m1]; z1:=CellZ[m1]; end;
  1051.        2,5: begin x1:=CellX[0];  z1:=CellZ[0]; end;
  1052.     end;
  1053.     case Side of
  1054.      1: begin x2:=CellX[0];  z2:=CellZ[0]; end;
  1055.      2: begin x2:=CellX[m3]; z2:=CellZ[m3]; end;
  1056.      3: begin
  1057.           x1:=CellX[m3]; z1:=CellZ[m3];
  1058.           x2:=CellX[m1]; z2:=CellZ[m1];
  1059.         end;
  1060.      4: PointSect2(0,m3);
  1061.      5: PointSect2(m3,m1);
  1062.      6: PointSect2(m1,0);
  1063.      7: begin PointSect1(m1,0); PointSect2(0,m3); end;
  1064.      8: begin PointSect1(0,m3); PointSect2(m3,m1); end;
  1065.      9: begin PointSect1(m3,m1); PointSect2(m1,0); end;
  1066.     End;
  1067.   end;
  1068.  
  1069. var x,y       : Integer;
  1070.     tmpYPosition:Integer;
  1071.     tmp1      : Double;
  1072.     tmp2      : Double;
  1073.     tmp3      : Double;
  1074.     tmp4      : Double;
  1075.     tmpIndex1 : Longint;
  1076.     tmpIndex2 : Longint;
  1077.     tmpIndex3 : Longint;
  1078.     tmpIndex4 : Longint;
  1079.  
  1080.   Procedure DrawLevel(TheLevel:Integer);
  1081.   Const Sides:Array[-1..1,-1..1,-1..1] of Integer=
  1082.                    ( ( (0,0,8),(0,2,5),(7,6,9) ),
  1083.                      ( (0,3,4),(1,3,1),(4,3,0) ),
  1084.                      ( (9,6,7),(5,2,0),(8,0,0) )  );
  1085.   var Corner      : Integer;
  1086.       SignHeights : Array[0..4] of Integer;
  1087.       Side        : Integer;
  1088.   Begin
  1089.     { corners dif Y }
  1090.     DifY[1]:=tmp1-FLevels[TheLevel];
  1091.     DifY[2]:=tmp3-FLevels[TheLevel];
  1092.     DifY[3]:=tmp4-FLevels[TheLevel];
  1093.     DifY[4]:=tmp2-FLevels[TheLevel];
  1094.     { center point dif Y }
  1095.     DifY[0] :=0.25*( DifY[1]+DifY[2]+DifY[3]+DifY[4] );
  1096.  
  1097.     With ParentChart.DepthAxis do
  1098.     begin
  1099.       CellZ[1]:=CalcXPosValue(ZValues[tmpIndex1]);
  1100.       CellZ[3]:=CalcXPosValue(ZValues[tmpIndex2]);
  1101.     end;
  1102.     CellZ[2]:=CellZ[1];
  1103.     CellZ[4]:=CellZ[3];
  1104.  
  1105.     CellX[1] := CalcXPos(tmpIndex1);
  1106.     CellX[2] := CalcXPos(tmpIndex3);
  1107.     CellX[3] := CellX[2];
  1108.     CellX[4] := CellX[1];
  1109.  
  1110.     for Corner:=0 to 4 do
  1111.     Begin
  1112.       if DifY[Corner]>0 then SignHeights[Corner]:= 1 else
  1113.       if DifY[Corner]<0 then SignHeights[Corner]:=-1 else
  1114.                              SignHeights[Corner]:=0;
  1115.     End;
  1116.  
  1117.     { mid X pos }
  1118.     CellX[0]:=( CellX[1] + CellX[2] ) div 2;
  1119.     { mid Z pos }
  1120.     CellZ[0]:=( CellZ[1] + CellZ[3] ) div 2;
  1121.  
  1122.     for Corner:=1 to 4 do
  1123.     Begin
  1124.       m1:=Corner;
  1125.       if Corner=4 then m3:=1 else m3:=Succ(Corner);
  1126.       Side:=Sides[SignHeights[m1],SignHeights[0],SignHeights[m3]];
  1127.       if Side<>0 then
  1128.       Begin
  1129.         CalcLinePoints(Side);
  1130.         With ParentChart,Canvas do
  1131.         begin
  1132.           if FYPositionLevel then
  1133.              tmpYPosition:=GetVertAxis.CalcYPosValue(FLevels[TheLevel]);
  1134.           MoveTo3D(x1,tmpYPosition,z1);
  1135.           LineTo3D(x2,tmpYPosition,z2);
  1136.         end;
  1137.       End;
  1138.     End;
  1139.   end;
  1140.  
  1141.   Function ExistFourGridIndex:Boolean;
  1142.   begin
  1143.     result:=False;
  1144.     tmpIndex1:=GetGridIndex(x,y);
  1145.     if tmpIndex1>-1 then
  1146.     begin
  1147.       tmpIndex2:=GetGridIndex(x,y+1);
  1148.       if tmpIndex2>-1 then
  1149.       begin
  1150.         tmpIndex3:=GetGridIndex(x+1,y);
  1151.         if tmpIndex3>-1 then
  1152.         begin
  1153.           tmpIndex4:=GetGridIndex(x+1,y+1);
  1154.           result:=tmpIndex4>-1;
  1155.         end;
  1156.       end;
  1157.     end;
  1158.   end;
  1159.  
  1160. var DiffMin  : Double;
  1161.     DiffMax  : Double;
  1162.     TheLevel : Integer;
  1163. begin
  1164.   if Count>0 then
  1165.   begin
  1166.     ParentChart.Canvas.Pen.Assign(FPen);
  1167.     tmpYPosition:=GetVertAxis.CalcYPosValue(FYPosition);
  1168.     for y:=1 to FNumZValues-1 do
  1169.       for x:=1 to FNumXValues-1 do
  1170.         if ExistFourGridIndex then
  1171.         begin
  1172.           With YValues do
  1173.           begin
  1174.             tmp1:=Value[tmpIndex1];
  1175.             tmp2:=Value[tmpIndex2];
  1176.             tmp3:=Value[tmpIndex3];
  1177.             tmp4:=Value[tmpIndex4];
  1178.           end;
  1179.  
  1180.           DiffMin  := MinDouble(MinDouble(tmp1,tmp2),MinDouble(tmp3,tmp4));
  1181.           DiffMax  := MaxDouble(MaxDouble(tmp1,tmp2),MaxDouble(tmp3,tmp4));
  1182.           if (DiffMax>=FLevels[0]) and (DiffMin<=FLevels[NumLevels-1]) then
  1183.           for TheLevel:=0 to NumLevels-1 do
  1184.           if (FLevels[TheLevel]>=DiffMin) and (FLevels[TheLevel]<=DiffMax) then
  1185.           begin
  1186.             ParentChart.Canvas.Pen.Color:=FLevelColors[TheLevel];
  1187.             DrawLevel(TheLevel);
  1188.           end;
  1189.         end;
  1190.   end;
  1191. end;
  1192.  
  1193. procedure TContourSeries.FillSampleValues(NumValues:Longint);
  1194. begin
  1195.   inherited FillSampleValues(NumValues);
  1196.   FYPosition:=0.5*(YValues.MaxValue+YValues.MinValue); { mid vertical pos }
  1197. end;
  1198.  
  1199. Procedure TContourSeries.PrepareForGallery(IsEnabled:Boolean);
  1200. begin
  1201.   inherited PrepareForGallery(IsEnabled);
  1202.   if not IsEnabled then SeriesColor:=clGray;
  1203.   UseColorRange:=False;
  1204.   UsePalette:=IsEnabled;
  1205. end;
  1206.  
  1207. Function TContourSeries.GetEditorClass:String;
  1208. Begin
  1209.   result:='TContourSeriesEditor'; { <-- dont translate ! }
  1210. end;
  1211.  
  1212. Procedure TContourSeries.SetPen(Value:TChartPen);
  1213. Begin
  1214.   FPen.Assign(Value);
  1215. End;
  1216.  
  1217. Function TContourSeries.CountLegendItems:Integer;
  1218. begin
  1219.   result:=FNumLevels;
  1220. end;
  1221.  
  1222. Function TContourSeries.LegendItemColor(LegendIndex:Longint):TColor;
  1223. begin  { inverted legend }
  1224.   result:=FLevelColors[FNumLevels-LegendIndex-1];
  1225. end;
  1226.  
  1227. Function TContourSeries.LegendString( LegendIndex:Integer;
  1228.                                       LegendTextStyle:TLegendTextStyle ):String;
  1229. begin { inverted legend }
  1230.   result:=FormatFloat(ValueFormat,FLevels[FNumLevels-LegendIndex-1]);
  1231. end;
  1232.  
  1233. Procedure TContourSeries.DoBeforeDrawChart; { calc Level values and colors }
  1234. Var t   : Integer;
  1235.     tmp : Double;
  1236. begin
  1237.   inherited DoBeforeDrawChart;
  1238.   tmp:=(YValues.MaxValue-YValues.MinValue)/FNumLevels;
  1239.   for t:=0 to FNumLevels-1 do
  1240.   begin
  1241.     FLevels[t]:=YValues.MinValue+1.0*tmp*t;
  1242.     if ColorEachPoint then
  1243.        FLevelColors[t]:=GetDefaultColor(t) else
  1244.     if UsePalette or UseColorRange then
  1245.        FLevelColors[t]:=GetValueColorValue(FLevels[t])
  1246.     else
  1247.        FLevelColors[t]:=SeriesColor;
  1248.     if Assigned(FOnGetLevel) then FOnGetLevel(Self,t,FLevels[t],FLevelColors[t]);
  1249.   end;
  1250. end;
  1251.  
  1252. Procedure Tee3DSeriesExitProc; far;
  1253. begin
  1254.   UnRegisterTeeSeries([TSurfaceSeries,TContourSeries]);
  1255. end;
  1256.  
  1257. initialization
  1258.   RegisterTeeSeries( TSurfaceSeries, TeeMsg_GallerySurface,
  1259.                      TeeMsg_GalleryExtended,1);
  1260.   RegisterTeeSeries( TContourSeries, TeeMsg_GalleryContour,
  1261.                      TeeMsg_GalleryExtended,1);
  1262. {$IFDEF D1}
  1263.   AddExitProc(Tee3DSeriesExitProc);
  1264. {$ENDIF}
  1265. {$IFNDEF D1}
  1266. finalization
  1267.   Tee3DSeriesExitProc;
  1268. {$ENDIF}
  1269. end.
  1270.